#### TODO自己做吧###
"""
Author:

"""
import zmq
import struct
import socket
import pickle
import time
import multiprocessing as mp
from typing import Dict, Tuple, Sequence, List
from utils.utils import *

def Server_Recv(_recv_dict : dict, _recv_flag : mp.Value, recv_port : int):  #
    print("Into_Server_Recv!")
    # 从MVS主程序中接收待分发数据
    context = zmq.Context(1)
    data_receiver = context.socket(zmq.PULL)
    data_receiver.connect("tcp://127.0.0.1:" + str(recv_port))
    # data_receiver.setsockopt(zmq.RCVTIMEO, 1000)
    
    lock = _recv_flag.get_lock()
    while True:
        # print("pc_server_recv")
        time.sleep(0.001)   # print("pc_server_recv") # TODO：此句可防止堵塞？换成延时函数亦可
        
        lock.acquire()
        try:
            _recv_flag.value = 0
            recv_pkg = data_receiver.recv(zmq.NOBLOCK) #zmq.NOBLOCK
            recv_msg = pickle.loads(recv_pkg)
            for i in range(len(recv_msg)):
                _recv_dict[recv_msg[i][0]] = recv_msg[i]
            print("Recv From MVS", _recv_dict)
            _recv_flag.value = 1
        except:
            # print("Sender Not Ready!")
            continue
        finally:
            lock.release()
    
def Server_Send(_distribute_dict : dict, _recv_flag : mp.Value, send_ports_head : int):
    # 解包分发到decision决策程序
    print("Into_Sender_Send!")
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # udp_socket.setblocking(0)
    
    while True:
        # TODO: 添加结束的时候弹出
        # print("pc_server_send")
        if _recv_flag.value == 0:
            # time.sleep(0.03)
            continue

        for key, value in _distribute_dict.items(): # 改key
            pkg = pickle.dumps(value)
            try:
                udp_socket.sendto(pkg, ("127.0.0.1", key + send_ports_head))
                print("Send to Decision!",value)
                _recv_flag.value = 0
            except:
                print("Sending Data Failed!")

if __name__ == '__main__':
    # 读取配置文件
    init_cfgs = process_yaml_cfg(path_to_configs='/root/code/workspace/src/MVS/Configs/', filename='InitConfigs.yaml')
    recv_port = init_cfgs.server_ports_cfg['recv_port']
    send_ports_head = init_cfgs.server_ports_cfg['send_ports_head']
    veh_params = init_cfgs.vehicle_init_msg['params']
    
    # PORTS = [recv_port]
    
    # for i, params in enumerate(veh_params):
    #     PORTS.append(send_ports_head + int(params[0]))
    
    # for port in PORTS:
    #     procs = find_procs_by_port(port)
    #     if procs:
    #         for proc in procs:
    #             print(f"Found process {proc.pid} occupying port {port}. Attempting to kill.")
    #             try:
    #                 kill_proc_tree(proc.pid)
    #             except psutil.NoSuchProcess:
    #                 pass
    #     else:
    #         print(f"No process found occupying port {port}.")
    
    
    
    #数据收发类型
    mgr = mp.Manager()
    _recv_dict = mgr.dict()
    
    _recv_flag = mp.Value('i', 0)
    
    pc1 = mp.Process(target=Server_Recv, args=(_recv_dict, _recv_flag, recv_port, ))   # 
    pc1.start()
    
    pc2 = mp.Process(target=Server_Send, args=(_recv_dict, _recv_flag, send_ports_head, ))   # 
    pc2.start()
    
    pc1.join()
    pc2.join()
      
# # 创建UDP socket 
#     udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#     # 绑定本地地址和端口
#     local_address = ('127.0.0.1', 5555)
#     udp_socket.bind(local_address)

#     # 接收数据
#     data, address = udp_socket.recvfrom(1024)

#     # 反序列化数据
#     received_list = pickle.loads(data)

#     print(received_list)

#     # 关闭socket
#     udp_socket.close()